use build_migrate::environment::EnvironmentResolver;
use build_migrate::config::EnvironmentVariablesConfig;
use build_migrate::core::BuildConfiguration;
use tempfile::tempdir;

#[test]
fn test_config_priority_system() {
    // 设置系统环境变量
    unsafe {
        std::env::set_var("TEST_SYSTEM_VAR", "system_value");
    }
    
    // 创建配置
    let mut config = EnvironmentVariablesConfig::default();
    config.use_system_env = true;
    
    // 配置文件映射（最高优先级）
    config.mappings.insert("TEST_SYSTEM_VAR".to_string(), "config_value".to_string());
    config.mappings.insert("CONFIG_ONLY_VAR".to_string(), "config_only".to_string());
    
    let temp_dir = tempdir().unwrap();
    let resolver = EnvironmentResolver::with_config(temp_dir.path().to_path_buf(), config);
    
    // 测试优先级：配置文件 > 系统环境变量
    let result = resolver.resolve_variables("$(TEST_SYSTEM_VAR)", &BuildConfiguration::Debug);
    assert_eq!(result, "config_value", "配置文件映射应该覆盖系统环境变量");
    
    let result = resolver.resolve_variables("$(CONFIG_ONLY_VAR)", &BuildConfiguration::Debug);
    assert_eq!(result, "config_only");
    
    // 清理环境变量
    unsafe {
        std::env::remove_var("TEST_SYSTEM_VAR");
    }
}

#[test]
fn test_system_env_disabled() {
    // 设置系统环境变量
    unsafe {
        std::env::set_var("TEST_DISABLED_VAR", "system_value");
    }
    
    let mut config = EnvironmentVariablesConfig::default();
    config.use_system_env = false; // 禁用系统环境变量
    
    let temp_dir = tempdir().unwrap();
    let resolver = EnvironmentResolver::with_config(temp_dir.path().to_path_buf(), config);
    
    // 应该保持未知变量不变，不读取系统环境变量
    let result = resolver.resolve_variables("$(TEST_DISABLED_VAR)", &BuildConfiguration::Debug);
    assert_eq!(result, "$(TEST_DISABLED_VAR)", "禁用系统环境变量时未知变量应保持不变");
    
    unsafe {
        std::env::remove_var("TEST_DISABLED_VAR");
    }
}


#[test]
fn test_complex_path_resolution() {
    let mut config = EnvironmentVariablesConfig::default();
    config.mappings.insert("BOOST_ROOT".to_string(), "C:/boost_1_75_0".to_string());
    config.mappings.insert("MY_LIBS".to_string(), "D:/Libraries".to_string());
    
    let temp_dir = tempdir().unwrap();
    let resolver = EnvironmentResolver::with_config(temp_dir.path().to_path_buf(), config);
    
    // 测试复杂路径解析
    let input = "$(BOOST_ROOT)/lib/$(Platform)_$(Configuration);$(MY_LIBS)/$(PlatformToolset)";
    let result = resolver.resolve_variables(input, &BuildConfiguration::Release);
    
    assert!(result.contains("C:/boost_1_75_0/lib/x64_Release"), "应该正确解析复合路径");
    assert!(result.contains("D:/Libraries/v143"), "应该包含库路径和工具集");
}

#[test]
fn test_path_list_resolution_with_config() {
    let mut config = EnvironmentVariablesConfig::default();
    config.mappings.insert("OPENCV_DIR".to_string(), "C:/opencv/build".to_string());
    config.mappings.insert("CUSTOM_INCLUDE".to_string(), "E:/MyIncludes".to_string());
    
    let temp_dir = tempdir().unwrap();
    let resolver = EnvironmentResolver::with_config(temp_dir.path().to_path_buf(), config);
    
    let paths = "$(OPENCV_DIR)/include;$(CUSTOM_INCLUDE);$(ProjectDir)/src;%(InheritedPaths)";
    let resolved_paths = resolver.resolve_path_list(paths, &BuildConfiguration::Debug);
    
    assert_eq!(resolved_paths.len(), 3, "应该过滤掉%(InheritedPaths)");
    
    let path_strings: Vec<String> = resolved_paths.iter()
        .map(|p| p.to_string_lossy().to_string())
        .collect();
    
    assert!(path_strings.iter().any(|p| p.contains("opencv")), "应该包含OpenCV路径");
    assert!(path_strings.iter().any(|p| p.contains("MyIncludes")), "应该包含自定义路径");
    assert!(path_strings.iter().any(|p| p.contains("src")), "应该包含项目源码路径");
}

#[test]
fn test_config_update() {
    let temp_dir = tempdir().unwrap();
    let mut resolver = EnvironmentResolver::new(temp_dir.path().to_path_buf());
    
    // 初始状态 - 未知变量保持不变
    let result = resolver.resolve_variables("$(CUSTOM_VAR)", &BuildConfiguration::Debug);
    assert_eq!(result, "$(CUSTOM_VAR)");
    
    // 更新配置
    let mut new_config = EnvironmentVariablesConfig::default();
    new_config.mappings.insert("CUSTOM_VAR".to_string(), "new_value".to_string());
    resolver.update_config(new_config);
    
    // 验证配置更新生效
    let result = resolver.resolve_variables("$(CUSTOM_VAR)", &BuildConfiguration::Debug);
    assert_eq!(result, "new_value");
}
